package com.aier.entrance.icsocket;

import java.util.HashMap;
import java.util.Map;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import com.aier.common.common.Constant;
import com.aier.entrance.common.EntranceICFinalData;
import com.aier.entrance.service.IEntranceCardService;


    
    /**
     * Class the extends IoHandlerAdapter in order to properly handle
     * connections and the data the connections send
     *
     * @author <a href="http://mina.apache.org" mce_href="http://mina.apache.org">Apache MINA Project</a>
     */
public class WatchingShortHandler extends IoHandlerAdapter {
    
    
    long[] flag =new long[]{-1};
    public static Map<String,String> snMap = new HashMap<String,String>();
    private IEntranceCardService ec;
    public WatchingShortHandler(IEntranceCardService ec) {
        this.ec = ec;
    }

    /**
     * 异常来关闭session
     */
    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
        throws Exception {
        cause.printStackTrace();
        session.close(true);
    }

    /**
     * 服务器端收到一个消息
     */
    @Override
    public void messageReceived(IoSession session, Object message)
        throws Exception {

        IoBuffer io = (IoBuffer) message;
        System.out.println(Thread.currentThread().getId() + "session" + session.getId() + message.toString());
        if (io.hasRemaining())
        {
            byte[] validBytes = new byte[io.remaining()];
            io.get(validBytes,0,io.remaining());
            if ((validBytes.length == WgUdpCommShort.WGPacketSize)
                    && (WgUdpCommShort.getIntByByte(validBytes[0]) == WgUdpCommShort.Type))  //型号固定
            {
                long sn = WgUdpCommShort.getLongByByte(validBytes, Constant.num_4, Constant.num_4);
                long recordIndexGet = WgUdpCommShort.getLongByByte(validBytes, Constant.num_8, Constant.num_4);
//                System.out.println("recordIndexGet="+recordIndexGet);
                
                //12    记录类型
                //0=无记录
                //1=刷卡记录
                //2=门磁,按钮, 设备启动, 远程开门记录
                //3=报警记录    1   
                int recordType = WgUdpCommShort.getIntByByte(validBytes[Constant.num_12]);
                System.out.println("接收到来自控制器SN = " + sn + " 的记录;刷卡类型为："+recordType);
                
                
                if (recordType == 1)
                {
                    String recordLast = snMap.get(sn+"");
                    if((null == recordLast) || ("".equals(recordLast))){ 
                        //遍历map,清除相同value的键值对
                        snMap.put(String.valueOf(sn), String.valueOf(recordIndexGet));
                    } else if (!String.valueOf(recordIndexGet).equals(recordLast)) {
                        
                        int direction = WgUdpCommShort.getIntByByte(validBytes[Constant.num_15]);
                        int doorNO = WgUdpCommShort.getIntByByte(validBytes[Constant.num_14]);
                        
                        //16-19 卡号(类型是刷卡记录时)
                        //或编号(其他类型记录)   4   
                        long  recordCardNO = WgUdpCommShort.getLongByByte(validBytes, Constant.num_16, Constant.num_4);
                        // 对卡号进行转换
                        recordCardNO = ((recordCardNO-recordCardNO%Constant.num_100000)/Constant.num_100000)*Constant.num_256*Constant.num_256+
                                (recordCardNO%Constant.num_100000);
                        // 刷卡时间 年月日时分秒 (采用BCD码)见设置时间部分的说明
                        String recordTime= String.format("%02X%02X-%02X-%02X %02X:%02X:%02X", 
                            WgUdpCommShort.getIntByByte(validBytes[Constant.num_20]),
                            WgUdpCommShort.getIntByByte(validBytes[Constant.num_21]),
                            WgUdpCommShort.getIntByByte(validBytes[Constant.num_22]),
                            WgUdpCommShort.getIntByByte(validBytes[Constant.num_23]),
                            WgUdpCommShort.getIntByByte(validBytes[Constant.num_24]),
                            WgUdpCommShort.getIntByByte(validBytes[Constant.num_25]),
                            WgUdpCommShort.getIntByByte(validBytes[Constant.num_26]));
                        System.out.println("刷卡时间："+recordTime+"; 进门、出门："+direction+"; 刷卡门号为："+doorNO+"; 卡号 为：" +recordCardNO);
                        
                        if (direction == 1) {
                            // 进门
                            flag = ec.updateSwingICCard(String.valueOf(sn),String.valueOf(recordCardNO),IEntranceCardService.OPERATE_IN,recordTime);
                            System.out.println("设备号" + TestMessageDecoder.snMap.get(session.getId() + "") + "; flag:" + flag[0]);
                            if((flag[0] == EntranceICFinalData.SWINGICCARD_STATE_USER_SUCCESS)||
                                     (flag[0] == EntranceICFinalData.SWINGICCARD_STATE_TEACHER_SUCCESS)||
                                         flag[0] == EntranceICFinalData.SWINGICCARD_STATE_SCHOOL_SUCCESS){
                                // 远程开门
                                openDoor(sn, session,doorNO);
                            }
                            
                        } else {
                            // 出门
                            flag = ec.updateSwingICCard(String.valueOf(sn),String.valueOf(recordCardNO),IEntranceCardService.OPERATE_OUT,recordTime);
                            System.out.println("设备号" + TestMessageDecoder.snMap.get(session.getId() + "") + "flag:" + flag[0]);
                            if((flag[0] == EntranceICFinalData.SWINGICCARD_STATE_USER_SUCCESS)||
                                     (flag[0] == EntranceICFinalData.SWINGICCARD_STATE_TEACHER_SUCCESS)||
                                         flag[0] == EntranceICFinalData.SWINGICCARD_STATE_SCHOOL_SUCCESS){
                                // 远程开门
                                openDoor(sn, session,doorNO);
                                 
                            }
                            
                        }
                        // 设置已读取过的记录索引号  设置的值为最后读取到的刷卡记录索引号
    //                        setRecordIndex(sn,session,recordIndexGet);
                        
                        // 获取已读取过的记录索引号
    //                        getRecordIndex(sn,session);
                        
                    }
                }
                
                
            } else
            {
                System.out.print("收到无效数据包: ????\r\n");
            }
        }
    }
    /**
     * 远程开门
     * @param sn 门禁控制器编码
     * @param session
     */
    public void openDoor(long sn,IoSession session,int doorNO){
        byte[] returnData = new byte[Constant.num_64];
        returnData[0] = Constant.num_0x19;
        returnData[1] = Constant.num_0x40;
        returnData[Constant.num_4] = (byte)(sn & Constant.num_ff);
        returnData[Constant.num_5] = (byte)(sn>>Constant.num_8 & Constant.num_ff);
        returnData[Constant.num_6] = (byte)(sn>>Constant.num_16 & Constant.num_ff);
        returnData[Constant.num_7] = (byte)(sn>>Constant.num_24 & Constant.num_ff);
        returnData[Constant.num_8] = (byte)(doorNO & Constant.num_ff);
        
        IoBuffer b = IoBuffer.allocate(Constant.num_64);
        b.put(returnData);
        b.flip();
        System.out.println(b);
        session.write(b);
    }
    
    public void setRecordIndex(long sn,IoSession session,long recordIndexGet) {
        byte[] returnData = new byte[Constant.num_64];
        returnData[0] = Constant.num_0x19;
        returnData[1] = Constant.num_0xB2;
        returnData[Constant.num_4] = (byte)(sn & Constant.num_ff);
        returnData[Constant.num_5] = (byte)(sn>>Constant.num_8 & Constant.num_ff);
        returnData[Constant.num_6] = (byte)(sn>>Constant.num_16 & Constant.num_ff);
        returnData[Constant.num_7] = (byte)(sn>>Constant.num_24 & Constant.num_ff);
        
//        returnData[Constant.num_8] = WgUdpCommShort.longToByte(recordIndexGet)[0];
//        returnData[Constant.num_9] = WgUdpCommShort.longToByte(recordIndexGet)[1];
//        returnData[Constant.num_10] = WgUdpCommShort.longToByte(recordIndexGet)[2];
//        returnData[Constant.num_11] = WgUdpCommShort.longToByte(recordIndexGet)[3];
        returnData[Constant.num_8] = (byte)(recordIndexGet & Constant.num_ff);
        returnData[Constant.num_9] = (byte)(recordIndexGet>>Constant.num_8 & Constant.num_ff);
        returnData[Constant.num_10] = (byte)(recordIndexGet>>Constant.num_16 & Constant.num_ff);
        returnData[Constant.num_11] = (byte)(recordIndexGet>>Constant.num_24 & Constant.num_ff);
        
        returnData[Constant.num_12] = WgUdpCommShort.longToByte(WgUdpCommShort.SpecialFlag)[0];
        returnData[Constant.num_13] = WgUdpCommShort.longToByte(WgUdpCommShort.SpecialFlag)[1];
        returnData[Constant.num_14] = WgUdpCommShort.longToByte(WgUdpCommShort.SpecialFlag)[2];
        returnData[Constant.num_15] = WgUdpCommShort.longToByte(WgUdpCommShort.SpecialFlag)[Constant.num_3];
        
        IoBuffer b = IoBuffer.allocate(Constant.num_64);
        b.put(returnData);
        b.flip();
        System.out.println(b);
        session.write(b);
    }
    
    public void getRecordIndex(long sn,IoSession session) {
        byte[] returnData = new byte[Constant.num_64];
        returnData[0] = Constant.num_0x19;
        returnData[1] = Constant.num_0xB4;
        returnData[Constant.num_4] = (byte)(sn & Constant.num_ff);
        returnData[Constant.num_5] = (byte)(sn>>Constant.num_8 & Constant.num_ff);
        returnData[Constant.num_6] = (byte)(sn>>Constant.num_16 & Constant.num_ff);
        returnData[Constant.num_7] = (byte)(sn>>Constant.num_24 & Constant.num_ff);
        
        IoBuffer b = IoBuffer.allocate(Constant.num_64);
        b.put(returnData);
        b.flip();
        System.out.println(b);
        session.write(b);
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        System.out.println("服务器端关闭session...");
    }

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        System.out.println("服务器端成功创建一个session...");
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status)
        throws Exception {
        System.out.println("Session idle...");
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        System.out.println("服务器端成功开启一个session...");
    }
    
}
